﻿using Core.SimpleTemp.Common;
using Core.Toolkit.Common;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Core.Toolkit.AutoMapperExtend.DataDictionary
{

    public static class ConcurrentDataDicPool
    {

        static IServiceProvider _serviceProvider;
        static ConcurrentDictionary<string, string> _dataDic = new ConcurrentDictionary<string, string>();
        /// <summary>
        /// 以Category分组
        /// </summary>
        static ConcurrentDictionary<string, List<DataDicModel>> _dataDicListByCategory = new ConcurrentDictionary<string, List<DataDicModel>>();


        static ConcurrentDataDicPool()
        {

        }
        public static void Initialization(IEnumerable<IConcurrentDataDicProvider> concurrentDataDicProviders)
        {

            foreach (IConcurrentDataDicProvider provider in concurrentDataDicProviders)
            {
                provider.LoadData(_dataDic, _dataDicListByCategory);
            }

            //using (var scope = _serviceProvider.CreateScope())
            //{
            //    var services = scope.ServiceProvider;
            //    var dataDicProviders = services.GetRequiredService<IEnumerable<IConcurrentDataDicProvider>>();
            //    foreach (IConcurrentDataDicProvider provider in dataDicProviders)
            //    {
            //        provider.LoadData(_dataDic, _dataDicListByCategory);
            //    }
            //}
        }

        public static string GetDicValue(string category, string key)
        {
            string value;
            if (_dataDic.TryGetValue($"{category}_{key}", out value))
                return value;
            else
                return null;
        }

        private static List<DataDicModel> GetDicObjListByCategory(string category)
        {
            _dataDicListByCategory.TryGetValue(category, out List<DataDicModel> value);
            return value;
        }

        public static List<KeyValue<string, string>> GeDataDicValueByCategory(string category)
        {
            var list = GetDicObjListByCategory(category);
            return list?.Select(obj => new KeyValue<string, string> { Key = obj.Key, Value = obj.Value })?.ToList();
        }

        public static List<KeyValue<string, List<KeyValue<string, string>>>> GeDataDicValueByCategory(params string[] categorys)
        {
            List<KeyValue<string, List<KeyValue<string, string>>>> ret = new List<KeyValue<string, List<KeyValue<string, string>>>>();
            foreach (var item in categorys)
            {
                var list = GeDataDicValueByCategory(item);
                ret.Add(new KeyValue<string, List<KeyValue<string, string>>>() { Key = item, Value = list });
            }
            return ret;
        }

        #region 热更新
        /// <summary>
        /// 热更新一组DataDic(对应的KEY没有值：添加，反之更新)
        /// </summary>
        /// <param name="category"></param>
        /// <param name="list"></param>
        public static void UpdateCategory(string category, List<DataDicModel> list) => _dataDicListByCategory[category] = list;
        /// <summary>
        /// 热更新一个DataDic(对应的KEY没有值：添加，反之更新)
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void UpdateDataDic(string key, string value) => _dataDic[key] = value;
        /// <summary>
        /// 删除一组DataDic
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool RemoveCategory(string key) => _dataDicListByCategory.TryRemove(key, out List<DataDicModel> value);

        /// <summary>
        /// 删除一个DataDic
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool RemoveDataDic(string key) => _dataDic.TryRemove(key, out string value);

        #endregion

        public static string CreateKey(string category, string key) => $"{category}_{key}";
    }


    //[AutoDi(typeof(ConcurrentDataDicPool), AutoDiAttribute.Singleton)]
    public interface IConcurrentDataDicPool
    {
        string GetDicValue(string category, string key);
        List<KeyValue<string, List<KeyValue<string, string>>>> GeDataDicValueByCategory(params string[] categorys);
        List<KeyValue<string, string>> GeDataDicValueByCategory(string category);


        /// <summary>
        /// 热更新一组DataDic(对应的KEY没有值：添加，反之更新)
        /// </summary>
        /// <param name="category"></param>
        /// <param name="list"></param>
        void UpdateCategory(string category, List<DataDicModel> list);
        /// <summary>
        /// 热更新一个DataDic(对应的KEY没有值：添加，反之更新)
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        void UpdateDataDic(string key, string value);
        /// <summary>
        /// 删除一组DataDic
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        bool RemoveCategory(string key);

        /// <summary>
        /// 删除一个DataDic
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        bool RemoveDataDic(string key);
    }
}

